import { Injectable } from '@nestjs/common';
// import { decode } from 'iconv-lite';
import { Upload } from './upload.model';
import { InjectModel } from '@nestjs/sequelize';
import path from 'path';
import { promises as fs } from 'fs';
import { RuntimeException } from 'src/exceptions/runtime.exception';
import { OssService } from 'src/oss/oss.service';
import { uniqueFilename, uploadDatePath } from 'src/utils';

@Injectable()
export class UploadService {
  constructor(
    private ossService: OssService,
    @InjectModel(Upload) private uploadModel: typeof Upload,
  ) {}

  async uploadFile(file: Express.Multer.File) {
    // 可能出现中文文件名乱码，需要转换成 utf-8
    // file.originalname = decode(
    //   Buffer.from(file.originalname, 'binary'),
    //   'utf-8',
    // );

    const created = new this.uploadModel({
      filename: file.filename,
      mimetype: file.mimetype,
      destination: file.destination.replaceAll('\\', '/'),
      size: file.size,
      path: file.path.replaceAll('\\', '/'),
    });

    return created.save();
  }

  async uploadOssFile(file: Express.Multer.File) {
    const destination = uploadDatePath().replaceAll('\\', '/');
    const filename = uniqueFilename(file);
    const up = path.join(destination, filename).replaceAll('\\', '/');
    const ossUrl = await this.ossService.uploadFile(file, up);

    console.log('ossUrl', ossUrl);

    if (!ossUrl) {
      throw new RuntimeException('上传 OSS 失败');
    }

    const created = new this.uploadModel({
      filename,
      mimetype: file.mimetype,
      destination,
      size: file.size,
      path: up,
    });

    return await created.save();
  }

  async getFileUrl(name: string) {
    const filename = decodeURIComponent(name);

    const filePath = path.join(process.cwd(), filename);

    // 获取文件后缀
    const ext = path.extname(filename);

    // 根据文件后缀设置响应头的 Content-Type
    let contentType = '';
    if (ext === 'jpg' || ext === 'jpeg') {
      contentType = 'image/jpeg';
    } else if (ext === 'png') {
      contentType = 'image/png';
    } else if (ext === 'gif') {
      contentType = 'image/gif';
    } else {
      // 如果是其他图片格式，可以根据需要添加更多条件
      // 默认为 application/octet-stream
      contentType = 'application/octet-stream';
    }

    return { contentType, filePath };
  }

  async getOssFileUrl(name: string) {
    const filename = decodeURIComponent(name);

    return this.ossService.getFileUrl(filename);
  }

  async deleteFile(name: string, sd = true) {
    const filename = decodeURIComponent(name);

    const filePath = path.join(process.cwd(), filename);

    const basename = path.basename(filename);

    const upload = await this.uploadModel.findOne({
      where: { filename: basename },
    });

    if (!upload) {
      throw new RuntimeException('文件不存在，删除失败', 1);
    }

    // 如果不需要真实删除图片，则可以保留
    if (!sd) {
      await fs.unlink(filePath);
    }

    await upload.destroy();

    return true;
  }

  async deleteOssFile(name: string, sd = true) {
    const filename = decodeURIComponent(name);

    const basename = path.basename(filename);

    const upload = await this.uploadModel.findOne({
      where: { filename: basename },
    });

    if (!upload) {
      throw new RuntimeException('文件不存在，删除失败', 1);
    }

    // 如果不需要真实删除图片，则可以保留
    if (!sd) {
      await this.ossService.deleteFile(filename);
    }

    await upload.destroy();

    return true;
  }
}
